package com.suxin.thread.schedule;

import com.suxin.thread.schedule.job.Job;
import com.suxin.thread.schedule.job.JobService;
import com.suxin.thread.schedule.task.TaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;

import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @author Tang
 * @classname MasterExecutor
 * @description [  ]
 * @date 2021/3/16 10:49
 * 两级调度模型：定时器任务线程池 > 任务线程池
 * 1级调度：主线程负责调度定时器线程
 *
 */
@Slf4j
public class MasterExecutor implements InitializingBean , DisposableBean {

    private static final ScheduledExecutorService EXECUTOR =
            new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors() + 1,
                    new CustomizableThreadFactory("my-schedule"));

    private JobService jobService;

    private TaskService taskService;

    /**
     * 要执行的任务
     */
    private List<Job> jobList;

    /**
     * 存放在运行的job任务
     */
    private Map<Integer, ScheduledFuture<?>> runningJobs;

    @Override
    public void afterPropertiesSet() throws Exception {
        this.init();
    }

    private void init() {
        log.info("初始化调度线程开始...");
        runningJobs = new ConcurrentHashMap<>(16);
        // 获取要执行的任务
        jobList = jobService.getJobOnline();
        jobList.forEach(this::exec);
        log.info("初始化调度线程完成...");
    }

    private void exec(Job job) {
        RunnableJob runnableJob = new RunnableJob(jobService,taskService,job);
        ScheduledFuture<?> schedule = EXECUTOR.schedule(runnableJob, 0, TimeUnit.SECONDS);
        runningJobs.put(job.getId(), schedule);
    }

    @Override
    public void destroy() throws Exception {

    }
}